package com.adv.ems.filters.report.after;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.adv.ems.constants.EmsConst;
import com.adv.ems.db.entity.*;
import com.adv.ems.filters.EnergyDataBaseFilter;
import com.adv.ems.filters.dto.FilterParam;
import com.adv.ems.filters.report.dto.ReportHourPoolDTO;
import com.adv.ems.manager.CollectPointManager;
import com.adv.ems.manager.EnergyDataCumulateManager;
import com.adv.ems.manager.EnergyDataCumulateReportHourManager;
import com.adv.ems.manager.SystemConfigManager;
import com.adv.ems.model.dto.ReportDataDealConfigDTO;
import com.adv.ems.model.vo.ResultVO;
import com.adv.ems.service.IncreaseValueService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.Date;
import java.util.List;

@Slf4j
@Component
public class HourReportAfterFilter extends EnergyDataBaseFilter<ReportHourPoolDTO, Boolean> {
    @Resource
    EnergyDataCumulateManager energyDataCumulateManager;
    @Resource
    CollectPointManager collectPointManager;
    @Resource
    IncreaseValueService increaseValueService;
    @Resource
    EnergyDataCumulateReportHourManager energyDataCumulateReportHourManager;
    @Resource
    SystemConfigManager systemConfigManager;

    @Override
    protected String getFilterName() {
        return "累积上传数据及报表小时数据统计";
    }

    @Override
    protected double getOrder() {
        return 0;
    }

    @Override
    protected boolean isBefore() {
        return false;
    }

    @Override
    protected String getType() {
        return ReportHourPoolDTO.class.getName();
    }

    @Override
    protected ResultVO<Boolean> handle(FilterParam<ReportHourPoolDTO> param) {
        param.getList().forEach(this::dealEachPointHour);
        return ResultVO.success(true);
    }

    private void dealEachPointHour(ReportHourPoolDTO reportHour) {
        CollectPointDO point = collectPointManager.getAllMap().get(reportHour.getPointId());
        log.info("统计采集点ID【{}】统计时间：【{}】开始", reportHour.getPointId(), DateUtil.formatDateTime(reportHour.getTime()));
        List<EnergyDataCumulateDO> hourDataList = rebuildCumulateData(reportHour, point);
        if (!hourDataList.isEmpty()) {
            rebuildHourReport(hourDataList, point, reportHour.getTime());
        }
        log.info("统计采集点ID【{}】统计时间：【{}】结束", reportHour.getPointId(), DateUtil.formatDateTime(reportHour.getTime()));
    }

    private void rebuildHourReport(List<EnergyDataCumulateDO> hourDataList, CollectPointDO point, Date hour) {
        Double increaseRealValue = 0d;
        Double increaseStandValue = 0d;
        Long firstId = null;
        Double firstValue = null;
        Long lastId = null;
        Double lastValue = null;
        for (EnergyDataCumulateDO data : hourDataList) {
            if (firstId == null) {
                firstId = data.getId();
                firstValue = data.getRealValue();
            }
            lastId = data.getId();
            lastValue = data.getRealValue();
            increaseRealValue = data.getIncreaseRealValue() + increaseRealValue;
            increaseStandValue = data.getIncreaseStandValue() + increaseStandValue;
        }
        Double increaseCashValue = 0d;
        if (increaseRealValue > 0) {
            increaseCashValue = increaseValueService.computeCashValueByPoint(increaseRealValue, hour, point);
        }
        energyDataCumulateReportHourManager.deleteByPointColDate(point.getId(), hour);
        EnergyDataCumulateReportHourDO reportHour = new EnergyDataCumulateReportHourDO();
        reportHour.setCollectPointId(point.getId());
        reportHour.setFirstId(firstId);
        reportHour.setFirstRealValue(firstValue);
        reportHour.setLastId(lastId);
        reportHour.setLastRealValue(lastValue);
        reportHour.setIncreaseRealValue(increaseRealValue);
        reportHour.setIncreaseStandValue(increaseStandValue);
        reportHour.setIncreaseCashValue(increaseCashValue);
        reportHour.setColDate(hour);
        reportHour.setCreateTime(new Date());
        energyDataCumulateReportHourManager.insertData(reportHour);
    }

    private List<EnergyDataCumulateDO> rebuildCumulateData(ReportHourPoolDTO reportHour, CollectPointDO point) {
        log.info("累积数据累计值更新开始");
        ReportDataDealConfigDTO config = getReportDataDealConfig();
        Date start = reportHour.getTime();
        Date end = new Date(reportHour.getTime().getTime() + Duration.ofHours(1L).toMillis() - 1);
        List<EnergyDataCumulateDO> coverData = energyDataCumulateManager.getAllDataByPonitTime(reportHour.getPointId(), start, end);
        log.info("数据数量【{}】", coverData.size());
        if (coverData.isEmpty()) {
            return coverData;
        }
        EnergyDataCumulateDO before = energyDataCumulateManager.getTimeBeforeOneData(reportHour.getPointId(), start);
        for (EnergyDataCumulateDO data : coverData) {
            //真实值累积
            Double increaseRealValue = increaseValueService.computeRealValueByPoint(before, data, point, config);
            data.setIncreaseRealValue(increaseRealValue);
            //标准煤值累积
            Double increaseStandValue = increaseValueService.computeStandValueByPoint(increaseRealValue, point);
            data.setIncreaseStandValue(increaseStandValue);
            energyDataCumulateManager.updateIncreaseValue(data.getId(), data.getColDate(), increaseRealValue, increaseStandValue);
            before = data;
        }
        log.info("累积数据累计值更新结束");
        return coverData;
    }

    private ReportDataDealConfigDTO getReportDataDealConfig() {
        List<SystemConfigDO> configs = systemConfigManager.selectByType(EmsConst.SystemConfigKey.SYSTEM_CONFIG_ORIGINAL_DATA_DEAL_CONFIG_KEY);
        if (CollectionUtil.isEmpty(configs)) {
            return new ReportDataDealConfigDTO();
        }
        return JSONUtil.toBean(JSONUtil.toJsonStr(configs.get(0).getValue()), ReportDataDealConfigDTO.class);
    }
}
